package com.finance.scheduler.service;

import com.finance.base.constant.BaseConstants;
import com.finance.scheduler.requestxml.PullDataBackRequest;
import com.finance.scheduler.responsexml.Response;
import com.finance.system.service.IConfigService;
import com.finance.util.DateUtil;
import com.finance.util.OKHTTPUtil;
import com.finance.util.encrypt.EncryptUtil;
import com.finance.util.xml.JaxbUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by gyw on 2017/4/25.
 */
@Component
public class LogisticsDataPullCallBacker {
    @Resource
    private IConfigService configService;
    @Autowired
    private TaskExecutor taskExecutor;

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 创建拉单回调请求
      * @param mailNos
     * @return
     */
    public PullDataBackRequest createPullDataBackRequest(String mailNos){
        PullDataBackRequest pullDataBackRequest = new PullDataBackRequest();
        String requestTime = DateUtil.dateFormat(new Date(),DateUtil.SIMPLE_SECOND_FORMAT);
        String digestKey = this.configService.findConfig(BaseConstants.SYSCONFIG_KEY_CHUYAN_OMS_DIGISTKEY);//秘钥
        String charset = BaseConstants.CHARSET;
        String str = requestTime + digestKey;
        pullDataBackRequest.setDigest(EncryptUtil.md5Base64(str,charset));
        pullDataBackRequest.setMailNos(mailNos);
        pullDataBackRequest.setRequestTime(requestTime);
        return pullDataBackRequest;
    }

    /**
     * 拉单回调
     * @param pullDataBackRequest
     * @return
     */
    public Response feedBack(PullDataBackRequest pullDataBackRequest) throws Exception {
        String pullCallbackUrl = this.configService.findConfig(BaseConstants.SYSCONFIG_KEY_CHUYAN_OMS_CALLBACK);//拉单回调地址
        String responseString = null;
        Map<String,String> param = new HashMap<String,String>();
        Response response = null;
        try {
            String paramStr = JaxbUtil.bean2xml(pullDataBackRequest);
            param.put("param",paramStr);
            responseString = OKHTTPUtil.postForm(pullCallbackUrl,param);
            response = JaxbUtil.converyToJavaBean(responseString,Response.class);
        } catch (Exception e) {
            logger.error("访问拉单回执接口异常"+ e.getMessage());
           throw e;
        }
        this.logger.debug("反馈报文{}，反馈响应{}", param.toString(), responseString);
        this.logger.debug("已反馈运单拉取情况{}", pullDataBackRequest.getMailNos());
        return response;
    }

    public void callback(String mailNos) {
        PullDataBackRequest pullDataBackRequest = this.createPullDataBackRequest(mailNos);
        logger.debug("拉单回调请求参数:{}", JaxbUtil.bean2xml(pullDataBackRequest));
        try {
            Response response = this.feedBack(pullDataBackRequest);
            if(response == null || !"00".equals(response.getErrorCode())){
                this.logger.error("拉单反馈失败:{}",response == null ? "" : response.getErrorCode() + response.getMessage());
            }else{
                logger.info("拉单回调结果:{}", JaxbUtil.bean2xml(response));
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    public void multiCallback(List<String> wayBillNums) {
        int len = wayBillNums.size();
        int count = len/1000 + (len%1000 > 0 ? 1 : 0 );
        int per = len/count;
        int per_end = len - per*(count-1);
        for(int i = 0;i < count;i++){
            List<String> subList = null;
            if(per != per_end && i == count-1){
                subList = wayBillNums.subList(per*i,len);
            }else{
                subList = wayBillNums.subList(per*i,per*(i+1));
            }
            final String mailNos = StringUtils.join(subList,",");
            this.taskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    LogisticsDataPullCallBacker.this.callback(mailNos);
                }
            });
        }
    }

}
